package cn.jofei.common.config;


import cn.jofei.common.util.Resource;
import cn.jofei.common.util.Utils;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.yaml.snakeyaml.Yaml;

import java.io.InputStream;
import java.util.Optional;

/**
 * yml配置注入
 *
 * @author bao
 * @version ngbao v1.0
 * @date 2022/2/24 17:38
 */
public class AppProperties {
    private static JSONObject conf;
    public static final Logger log = LoggerFactory.getLogger(AppProperties.class);

    private static final String CONF_NAME = "application";
    private static final String CONF_SUFFIX = ".yml";

    private AppProperties() {
    }

    public static String get(String str) {
        return get(str, String.class).orElse("");
    }

    public static <T> Optional<T> get(String str, Class<T> clazz) {
        if (Utils.isNull(str)) return Optional.empty();
        String[] split = str.split("\\.");
        JSONObject object = conf;
        int len = split.length - 1;
        for (int i = 0; i < len; i++) {
            try {
                object = object.getJSONObject(split[i]);
            } catch (Exception e) {
                object = null;
                log.debug("没有配置: [{}]，将使用默认值", str);
                break;
            }
        }
        return Optional.ofNullable(object).map(e -> e.getObject(split[len], clazz));
    }

    static {
        if (conf == null) {
            synchronized (AppProperties.class) {
                //先判断当前对象是否已经创建
                if (conf == null) {
                    Yaml yaml = new Yaml();
                    InputStream in = null;
                    try {
                        in = Resource.loadAsStream(CONF_NAME + CONF_SUFFIX);
                        if (in == null) {
                            in = Resource.loadAsStream(Resource.CLASS_PATH + CONF_NAME + CONF_SUFFIX);
                            log.info("使用程序内置配置");
                        } else {
                            log.info("使用程序目录下的配置: " + CONF_NAME + CONF_SUFFIX);
                        }
                        AppProperties.conf = yaml.loadAs(in, JSONObject.class);
                        Utils.safeClose(in);
                        String act = get("profiles.active");
                        if (Utils.nonNull(act)) {
                            String profileName = CONF_NAME + "-" + act + CONF_SUFFIX;
                            log.info("激活的配置: " + profileName);
                            in = Resource.loadAsStream(profileName);
                            if (in == null) {
                                log.info("加载内部的配置: " + profileName);
                                in = Resource.loadAsStream(Resource.CLASS_PATH + profileName);
                            }
                            if (in != null) {
                                AppProperties.conf.putAll(yaml.loadAs(in, JSONObject.class));
                            }
                        }
                    } catch (Exception e) {
                        log.error("初始化配置出错", e);
                    } finally {
                        Utils.safeClose(in);
                    }
                }
            }
        }
    }

    /**
     * 替换属性值
     *
     * @param line
     * @return
     */
    public static String replaceVar(String line) {
        while (Utils.nonNull(line) && line.contains("${") && line.contains("}")) {
            String replacer = line.substring(line.indexOf("${") + 2, line.indexOf("}"));
            String property = AppProperties.get(replacer);
            line = line.replaceFirst("\\$\\{" + replacer + "}", Optional.ofNullable(property).orElse(""));
        }
        return line;
    }
}
